package core;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;

public class SetRecord extends Record {
	
	private static final long serialVersionUID = 7520523204137568585L;
	public static final String[] fieldNames = 
		{"Date", "Description", "Leader"};
	public static final String[] elementNames = 
		{"DATE", "DESCRIPTION", "LEADER"};
	public static final int DATE = 0,
								DESCRIPTION = 1,
								LEADER = 2;
	public static final int NUM_FIELDS = 3;
	
	
	private Object[] fields;
	private ArrayList items;
	
	public SetRecord(int id) {
		super(id);
		// add the current date when creating the set
		fields = new Object[NUM_FIELDS];
		items = new ArrayList<Presentable>();
		setField(DATE, new Date());
	}
	
	public Object getField(int i) {
		return fields[i];
	}
	public void setField(int i, Object obj) {
		fields[i] = obj;
	}
	
	public Presentable getItem(int i, SongIndex index) {
		if (i>=0 && i<items.size()) {
			Object obj = items.get(i);
			if (obj instanceof Presentable)
				return (Presentable)obj;
			else if (obj instanceof Integer)
				return index.get((Integer)obj);
		}
		
		return null;
	}
	public int getItemCount() {
		return items.size();
	}
	@SuppressWarnings("unchecked")
	public void moveItem(int from, int to) {
		if (rangeCheck(from) && rangeCheck(to)) {
			Object obj = items.remove(from);
			items.add(to, obj);
		}
	}
	private boolean rangeCheck(int i) {
		return (i >= 0 && i < items.size());
	}
	
	/**
	 * Returns a newly allocated array of all the Presentable
	 * items in the set.
	 * @return
	 */
	public Presentable[] getItems(SongIndex index) {
		Presentable[] ary = new Presentable[items.size()];
		for (int i=0; i<ary.length; i++)
			ary[i] = getItem(i, index);
		return ary;
	}
	
	/**
	 * Adds an item to the end of the set only if the item
	 * doesn't already exist.
	 * @param p		a Presentable item
	 */
	@SuppressWarnings("unchecked")
	public void add(Presentable p) {
		if (!items.contains(p) &&
				!(p instanceof SongRecord && items.contains((Integer)((SongRecord)p).getId()) ))
			items.add(p);
	}
	
	/**
	 * Adds an item to the given index in the set only if the item
	 * doesn't already exist.
	 * @param i		index
	 * @param p		a Presentable item
	 */
	@SuppressWarnings("unchecked")
	public void add(int i, Presentable p) {
		if (!items.contains(p) &&
				!(p instanceof SongRecord && items.contains((Integer)((SongRecord)p).getId()) ))
			items.add(i, p);
	}
	
	/**
	 * Removes an item from the set.
	 * @param p		a Presentable item
	 */
	public void remove(Presentable p) {
		items.remove(p);
	}
	
	/**
	 * Removes the item at index i from the set.
	 * @param i		index of the item
	 */
	public void remove(int i) {
		items.remove(i);
	}
	
	/**
	 * Prints the list of Presentable items in the set. 
	 */
	public String toString() {
		return "SetRecord: " + items.toString();
	}
	
	
	// Serialization methods
	@SuppressWarnings("unchecked")
	private void writeObject(ObjectOutputStream out) throws IOException {
		out.writeObject(fields);
		
		// replace all song records with their song IDs
		for (int i=0; i<items.size(); i++) {
			Object obj = items.get(i);
			if (obj instanceof SongRecord)
				items.set(i, ((SongRecord)obj).getId());
		}
		
		out.writeObject(items);
		
		/*
		ListIterator<Presentable> li = items.listIterator();
		ArrayList<SongRecord> songs = new ArrayList<SongRecord>();
		// remove all song records from presentables list
		while (li.hasNext()) {
			Presentable p = li.next();
			if (p instanceof SongRecord) {
				songs.add((SongRecord)p);
				li.remove();
			}
		}
		// write the non-song record presentables arraylist
		
		// write the song IDs as an array
		int[] songIDs = new int[songs.size()];
		for (int i=0; i<songIDs.length; i++)
			songIDs[i] = songs.get(i).getId();
		out.writeObject(songIDs);*/
	}
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		fields = (Object[])in.readObject();
		items = (ArrayList)in.readObject();
	}
}